using System;
using System.Collections.Generic;

namespace lucere.service.search
{
	///<summary>
	/// Encapsulates sort criteria for returned hits.
	///
	/// <p>The fields used to determine sort order must be carefully chosen.
	/// Documents must contain a single term in such a field,
	/// and the value of the term should indicate the document's relative position in
	/// a given sort order.  The field must be indexed, but should not be tokenized,
	/// and does not need to be stored (unless you happen to want it back with the
	/// rest of your document data).  
	/// <h3>Valid Types of Values</h3>
	///</p>
	/// <p>There are four possible kinds of term values which may be put into
	/// sorting fields: Integers, Longs, Floats, or Strings.  Unless
	/// <see cref="ISortField"></see> objects are specified, the type of value
	/// in the field is determined by parsing the first term in the field.
	/// </p>
	/// Integer term values should contain only digits and an optional
	/// preceding negative sign.  Values must be base 10 and in the range
	/// <code>Integer.MIN_VALUE</code> and <code>Integer.MAX_VALUE</code> inclusive.
	/// Documents which should appear first in the sort
	/// should have low value integers, later documents high values
	/// (i.e. the documents should be numbered <code>1..n</code> where
	/// <code>1</code> is the first and <code>n</code> the last).
	///
	/// <p>Long term values should contain only digits and an optional
	/// preceding negative sign.  Values must be base 10 and in the range
	/// <code>Long.MIN_VALUE</code> and <code>int.MaxValue</code> inclusive.
	/// Documents which should appear first in the sort
	/// should have low value integers, later documents high values.
	/// 
	/// <p>Float term values should conform to values accepted by
	/// <see cref="float.Parse(string)"></see> (except that <code>NaN</code>
	/// and <code>Infinity</code> are not supported).
	/// Documents which should appear first in the sort
	/// should have low values, later documents high values.
	///
	/// </p>String term values can contain any valid String, but should
	/// not be tokenized.  The values are sorted according to their
	/// <see cref="IComparable"></see> natural order.  Note that using this type
	/// of term value has higher memory requirements than the other
	/// two types.
	///
	/// <p>
	/// <h3>Object Reuse</h3>
	///
	/// </p>One of these objects can be
	/// used multiple times and the sort order changed between usages.
	///
	/// <p>This class is thread safe.
	///
	/// </p><h3>Memory Usage</h3>
	///
	/// <p>Sorting uses of caches of term values maintained by the
	/// internal HitQueue(s).  The cache is static and contains an integer
	/// or float array of length <code>IIndexReader.MaxDoc()</code> for each field
	/// name for which a sort is performed.  In other words, the size of the
	/// cache in bytes is:
	///
	/// </p><code>4 ///IIndexReader.MaxDoc() /// (# of different fields actually used to sort)</code>
	///
	/// </p>For String fields, the cache is larger: in addition to the
	/// above array, the value of every term in the field is kept in memory.
	/// If there are many unique terms in the field, this could
	/// be quite large.
	///
	/// <p>Note that the size of the cache is not affected by how many
	/// fields are in the index and <i>might</i> be used to sort - only by
	/// the ones actually used to sort a result set.
	///
	/// </p>
	/// </summary>
	public interface ISort : IEquatable<ISort>
	{
		/// <summary>
		/// Gets the sort to the given criteria.
		/// </summary>
		/// <param name="field"></param>
		/// <returns></returns>
		ISort GetSort(ISortField field);
		/// <summary>
		/// Gets the sort to the given criteria.
		/// </summary>
		/// <param name="field"></param>
		/// <returns></returns>
		void SetSort(ISortField field);

		/// <summary>
		/// Sets the sort to the given criteria in succession.
		/// </summary>
		/// <param name="fields"></param>
		/// <returns></returns>
		void SetSort(IEnumerable<ISortField> fields);

		///<summary>
		/// Representation of the sort criteria.
		/// return Array of SortField objects used in this sort criteria
		///</summary>
		IEnumerable<ISortField> GetSort();

	}
}